]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
extensions-app: Turn Extension into a GObject
authorFlorian Müllner <fmuellner@gnome.org>
Tue, 19 Dec 2023 17:45:04 +0000 (18:45 +0100)
committerMarge Bot <marge-bot@gnome.org>
Thu, 21 Dec 2023 15:24:23 +0000 (15:24 +0000)
This makes the Extension class usable as item-type in models,
and allows us to use property bindings.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3067>

subprojects/extensions-app/js/extensionManager.js
subprojects/extensions-app/js/extensionRow.js

index 25f02618e08e5ad912270ed319e27f1ec53f16d9..7671fb75e1ba833e9630646d94cc00c3f15d4406 100644 (file)
@@ -25,8 +25,69 @@ function loadInterfaceXML(iface) {
     return null;
 }
 
-class Extension {
+const Extension = GObject.registerClass({
+    GTypeName: 'Extension',
+    Properties: {
+        'uuid': GObject.ParamSpec.string(
+            'uuid', null, null,
+            GObject.ParamFlags.READABLE,
+            ''),
+        'name': GObject.ParamSpec.string(
+            'name', null, null,
+            GObject.ParamFlags.READABLE,
+            ''),
+        'description': GObject.ParamSpec.string(
+            'description', null, null,
+            GObject.ParamFlags.READABLE,
+            ''),
+        'state': GObject.ParamSpec.int(
+            'state', null, null,
+            GObject.ParamFlags.READABLE,
+            1, 99, ExtensionState.INITIALIZED),
+        'creator': GObject.ParamSpec.string(
+            'creator', null, null,
+            GObject.ParamFlags.READABLE,
+            ''),
+        'url': GObject.ParamSpec.string(
+            'url', null, null,
+            GObject.ParamFlags.READABLE,
+            ''),
+        'version': GObject.ParamSpec.string(
+            'version', null, null,
+            GObject.ParamFlags.READABLE,
+            ''),
+        'error': GObject.ParamSpec.string(
+            'error', null, null,
+            GObject.ParamFlags.READABLE,
+            ''),
+        'has-error': GObject.ParamSpec.boolean(
+            'has-error', null, null,
+            GObject.ParamFlags.READABLE,
+            false),
+        'has-prefs': GObject.ParamSpec.boolean(
+            'has-prefs', null, null,
+            GObject.ParamFlags.READABLE,
+            false),
+        'has-update': GObject.ParamSpec.boolean(
+            'has-update', null, null,
+            GObject.ParamFlags.READABLE,
+            false),
+        'has-version': GObject.ParamSpec.boolean(
+            'has-version', null, null,
+            GObject.ParamFlags.READABLE,
+            false),
+        'can-change': GObject.ParamSpec.boolean(
+            'can-change', null, null,
+            GObject.ParamFlags.READABLE,
+            false),
+        'is-user': GObject.ParamSpec.boolean(
+            'is-user', null, null,
+            GObject.ParamFlags.READABLE,
+            false),
+    },
+}, class Extension extends GObject.Object {
     constructor(variant) {
+        super();
         this.update(variant);
     }
 
@@ -43,30 +104,79 @@ class Extension {
         if (this._uuid !== uuid)
             throw new Error(`Invalid update of extension ${this._uuid} with data from ${uuid}`);
 
+        this.freeze_notify();
+
         const {name} = metadata;
-        this._name = name;
-        [this._keywords] = GLib.str_tokenize_and_fold(name, null);
+        if (this._name !== name) {
+            [this._keywords] = GLib.str_tokenize_and_fold(name, null);
+
+            this._name = name;
+            this.notify('name');
+        }
 
         const [desc] = metadata.description.split('\n');
-        this._description = desc;
+        if (this._description !== desc) {
+            this._description = desc;
+            this.notify('description');
+        }
 
-        this._type = type;
-        this._errorDetail = error;
-        this._state = state;
+        if (this._type !== type) {
+            this._type = type;
+            this.notify('is-user');
+        }
+
+        if (this._errorDetail !== error) {
+            this._errorDetail = error;
+            this.notify('error');
+        }
+
+        if (this._state !== state) {
+            const hadError = this.hasError;
+            this._state = state;
+            this.notify('state');
+
+            if (this.hasError !== hadError) {
+                this.notify('has-error');
+                this.notify('error');
+            }
+        }
 
         const creator = metadata.creator ?? '';
-        this._creator = creator;
+        if (this._creator !== creator) {
+            this._creator = creator;
+            this.notify('creator');
+        }
 
         const url = metadata.url ?? '';
-        this._url = url;
+        if (this._url !== url) {
+            this._url = url;
+            this.notify('url');
+        }
 
         const version = String(
             metadata['version-name'] || metadata['version'] || '');
-        this._version = version;
+        if (this._version !== version) {
+            this._version = version;
+            this.notify('version');
+            this.notify('has-version');
+        }
 
-        this._hasPrefs = hasPrefs;
-        this._hasUpdate = hasUpdate;
-        this._canChange = canChange;
+        if (this._hasPrefs !== hasPrefs) {
+            this._hasPrefs = hasPrefs;
+            this.notify('has-prefs');
+        }
+
+        if (this._hasUpdate !== hasUpdate) {
+            this._hasUpdate = hasUpdate;
+            this.notify('has-update');
+        }
+
+        if (this._canChange !== canChange) {
+            this._canChange = canChange;
+            this.notify('can-change');
+        }
+
+        this.thaw_notify();
     }
 
     get uuid() {
@@ -148,7 +258,9 @@ class Extension {
     get isUser() {
         return this._type === ExtensionType.PER_USER;
     }
-}
+});
+const {$gtype: TYPE_EXTENSION} = Extension;
+export {TYPE_EXTENSION as Extension};
 
 export const ExtensionManager = GObject.registerClass({
     Properties: {
@@ -166,9 +278,9 @@ export const ExtensionManager = GObject.registerClass({
             false),
     },
     Signals: {
-        'extension-added': {param_types: [GObject.TYPE_JSOBJECT]},
-        'extension-removed': {param_types: [GObject.TYPE_JSOBJECT]},
-        'extension-changed': {param_types: [GObject.TYPE_JSOBJECT], flags: GObject.SignalFlags.DETAILED},
+        'extension-added': {param_types: [Extension]},
+        'extension-removed': {param_types: [Extension]},
+        'extension-changed': {param_types: [Extension], flags: GObject.SignalFlags.DETAILED},
         'extensions-loaded': {},
     },
 }, class ExtensionManager extends GObject.Object {
index d2bb2c4981bc72370fc0043ffd1aad0daf0feb23..9085566cb8dc75ff6354770adc48853b719a2f00 100644 (file)
@@ -4,10 +4,17 @@ import Gio from 'gi://Gio';
 import GObject from 'gi://GObject';
 
 import {ExtensionState}  from './misc/extensionUtils.js';
+import {Extension} from './extensionManager.js';
 
 export const ExtensionRow = GObject.registerClass({
     GTypeName: 'ExtensionRow',
     Template: 'resource:///org/gnome/Extensions/ui/extension-row.ui',
+    Properties: {
+        'extension': GObject.ParamSpec.object(
+            'extension', null, null,
+            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
+            Extension),
+    },
     InternalChildren: [
         'detailsPopover',
         'descriptionLabel',
@@ -19,11 +26,10 @@ export const ExtensionRow = GObject.registerClass({
         'actionsBox',
     ],
 }, class ExtensionRow extends Adw.ActionRow {
-    _init(extension) {
-        super._init();
+    constructor(extension) {
+        super({extension});
 
         this._app = Gio.Application.get_default();
-        this._extension = extension;
 
         this._actionGroup = new Gio.SimpleActionGroup();
         this.insert_action_group('row', this._actionGroup);
@@ -89,7 +95,11 @@ export const ExtensionRow = GObject.registerClass({
     }
 
     get extension() {
-        return this._extension;
+        return this._extension ?? null;
+    }
+
+    set extension(ext) {
+        this._extension = ext;
     }
 
     _updateState() {